{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\".\\\\diyLogo.png\" alt=\"some_text\">\n",
    "<h1> 第四讲 函数及模块基础</h1>\n",
    "<a id=backup></a>\n",
    "<H2>目录</H2>  \n",
    "\n",
    "[4.1 Python函数](#Section1)  \n",
    "[4.2 Python模块](#Section2)  \n",
    "[4.3 Numpy ](#Section3)     \n",
    "[4.4 Pandas ](#Section4)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id = Section1> </a>\n",
    "## 4.1 Python函数\n",
    "函数是组织好的，可重复使用的，用来实现单一，或相关联功能的代码段。\n",
    "\n",
    "函数能提高应用的模块性，和代码的重复利用率。你已经知道Python提供了许多内建函数，比如print()。但你也可以自己创建函数，这被叫做用户自定义函数。\n",
    "### 4.1.1定义一个函数\n",
    "你可以定义一个由自己想要功能的函数，以下是简单的规则：\n",
    "\n",
    "+ 函数代码块以 def 关键词开头，后接函数标识符名称和圆括号 ()。  \n",
    "+ 任何传入参数和自变量必须放在圆括号中间，圆括号之间可以用于定义参数。  \n",
    "+ 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。  \n",
    "+ 函数内容以冒号 : 起始，并且缩进。  \n",
    "+ return [表达式] 结束函数，选择性地返回一个值给调用方，不带表达式的 return 相当于返回 None。\n",
    "<img src=\"./img/Function_1.png\" alt=\"some_text\" width=450>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.2语法\n",
    "Python 定义函数使用 def 关键字，一般格式如下：  \n",
    "def 函数名（参数列表）:    \n",
    "> 函数体"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World!\n"
     ]
    }
   ],
   "source": [
    "def hello() :\n",
    "    print(\"Hello World!\")\n",
    "\n",
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5\n"
     ]
    }
   ],
   "source": [
    "def max(i, j):\n",
    "    if i > j:\n",
    "        return i\n",
    "    else:\n",
    "        return j\n",
    " \n",
    "a = 4\n",
    "b = 5\n",
    "print(max(a, b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Welcome zhansan\n",
      "width = 4  height = 5  area = 20\n"
     ]
    }
   ],
   "source": [
    "# 计算面积函数\n",
    "def area(width, height):\n",
    "    return width * height\n",
    " \n",
    "def print_welcome(name):\n",
    "    print(\"Welcome\", name)\n",
    " \n",
    "print_welcome(\"zhansan\")\n",
    "w = 4\n",
    "h = 5\n",
    "print(\"width =\", w, \" height =\", h, \" area =\", area(w, h))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.3函数调用\n",
    "定义一个函数：给了函数一个名称，指定了函数里包含的参数，和代码块结构。\n",
    "\n",
    "这个函数的基本结构完成以后，你可以通过另一个函数调用执行，也可以直接从 Python 命令提示符执行。\n",
    "\n",
    "如下实例调用了 printme() 函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "我要调用用户自定义函数!\n",
      "再次调用同一函数\n"
     ]
    }
   ],
   "source": [
    "# 定义函数\n",
    "def printme( str ):\n",
    "   # 打印任何传入的字符串\n",
    "   print (str)\n",
    "   return\n",
    " \n",
    "# 调用函数\n",
    "printme(\"我要调用用户自定义函数!\")\n",
    "printme(\"再次调用同一函数\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 可更改(mutable)与不可更改(immutable)对象\n",
    "在 python 中，strings, tuples, 和 numbers 是不可更改的对象，而 list,dict 等则是可以修改的对象。\n",
    "\n",
    "+ 不可变类型：变量赋值 a=5 后再赋值 a=10，这里实际是新生成一个 int 值对象 10，再让 a 指向它，而 5 被丢弃，不是改变 a 的值，相当于新生成了 a。\n",
    "\n",
    "+ 可变类型：变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改，本身la没有动，只是其内部的一部分值被修改了。\n",
    "\n",
    "### python 函数的参数传递：\n",
    "\n",
    "+ 不可变类型：类似 C++ 的值传递，如整数、字符串、元组。如 fun(a)，传递的只是 a 的值，没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值，则是新生成一个 a 的对象。\n",
    "\n",
    "+ 可变类型：类似 C++ 的引用传递，如 列表，字典。如 fun(la)，则是将 la 真正的传过去，修改后 fun 外部的 la 也会受影响\n",
    "\n",
    "python 中一切都是对象，严格意义我们不能说值传递还是引用传递，我们应该说传不可变对象和传可变对象。\n",
    "\n",
    "python 传不可变对象实例\n",
    "通过 id() 函数来查看内存地址变化："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1884012439856\n",
      "1884012439856\n",
      "1884012440144\n"
     ]
    }
   ],
   "source": [
    "#查看参数id\n",
    "def change(a):#虚实结合，避免用局部变量做参数\n",
    "    print(id(a))   # 指向的是同一个对象\n",
    "    a=10\n",
    "    print(id(a))   # 一个新对象\n",
    " \n",
    "a=1\n",
    "print(id(a))\n",
    "change(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看见在调用函数前后，形参和实参指向的是同一个对象（对象 id 相同），在函数内部修改形参后，形参指向的是不同的 id。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 传可变对象实例\n",
    "可变对象在函数里修改了参数，那么在调用这个函数的函数里，原始的参数也被改变了。例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内取值1:  [10, 20, 30, [1, 2, 3, 4]]\n",
      "函数外取值2:  [10, 20, 30, [1, 2, 3, 4]]\n"
     ]
    }
   ],
   "source": [
    "# 传入可变对象\n",
    "def changeme( mylist ):\n",
    "   \"修改传入的列表\"\n",
    "   mylist.append([1,2,3,4])\n",
    "   print (\"函数内取值1: \", mylist)\n",
    "   return \n",
    " \n",
    "# 调用changeme函数\n",
    "mylist = [10,20,30]\n",
    "changeme( mylist )\n",
    "print (\"函数外取值2: \", mylist)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.4参数\n",
    "以下是调用函数时可使用的正式参数类型：\n",
    "\n",
    "+ 必需参数\n",
    "+ 关键字参数\n",
    "+ 默认参数\n",
    "+ 不定长参数\n",
    "#### 必需参数\n",
    "必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。\n",
    "\n",
    "调用 printme() 函数，你必须传入一个参数，不然会出现语法错误："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n"
     ]
    }
   ],
   "source": [
    "#无参数则出错\n",
    "def printme( str ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print (str)\n",
    "   return\n",
    " \n",
    "# 调用 printme 函数，不加参数会报错\n",
    "printme(\"hello\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 关键字参数\n",
    "关键字参数和函数调用关系紧密，函数调用使用关键字参数来确定传入的参数值。\n",
    "\n",
    "使用关键字参数允许函数调用时参数的顺序与声明时不一致，因为 Python 解释器能够用参数名匹配参数值。\n",
    "\n",
    "以下实例在函数 printme() 调用时使用参数名："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你是菜鸟\n"
     ]
    }
   ],
   "source": [
    "#使用关键字传入参数\n",
    "def printme( str ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print (str)\n",
    "   return\n",
    " \n",
    "#调用printme函数\n",
    "printme( str = \"你是菜鸟\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "名字:  zhansan\n",
      "年龄:  30\n"
     ]
    }
   ],
   "source": [
    "#以下实例中演示了函数参数的使用不需要使用指定顺序：\n",
    "def printinfo( name, age ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print (\"名字: \", name)\n",
    "   print (\"年龄: \", age)\n",
    "   return\n",
    " \n",
    "#调用printinfo函数\n",
    "printinfo( age=30, name=\"zhansan\" )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 默认参数\n",
    "调用函数时，如果没有传递参数，则会使用默认参数。以下实例中如果没有传入 age 参数，则使用默认值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "名字:  大橘子\n",
      "年龄:  50\n",
      "------------------------\n",
      "名字:  二狗子\n",
      "年龄:  35\n"
     ]
    }
   ],
   "source": [
    "#函数默认参数实例\n",
    "def printinfo( name, age = 35 ):\n",
    "   \"打印任何传入的字符串\"\n",
    "   print (\"名字: \", name)\n",
    "   print (\"年龄: \", age)\n",
    "   return\n",
    " \n",
    "#调用printinfo函数\n",
    "printinfo( age=50, name=\"大橘子\" )\n",
    "print (\"------------------------\")\n",
    "printinfo( name=\"二狗子\" )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 不定长参数\n",
    "你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数，和上述 2 种参数不同，声明时不会命名。\n",
    "\n",
    "基本语法如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def functionname([formal_args,] *var_args_tuple ):   \n",
    "   \"函数_文档字符串\"   \n",
    "   function_suite   \n",
    "   return [expression] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输出: \n",
      "70\n",
      "(60, 50)\n"
     ]
    }
   ],
   "source": [
    "# 不定长函数参数实例\n",
    "def printinfo( arg1, *vartuple ):\n",
    "   \"打印任何传入的参数\"\n",
    "   print (\"输出: \")\n",
    "   print (arg1)\n",
    "   print (vartuple)\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo( 70, 60, 50 )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果在函数调用时没有指定参数，它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输出1: \n",
      "10\n",
      "输出1: \n",
      "70\n",
      "输出2： 60\n",
      "输出2： 50\n"
     ]
    }
   ],
   "source": [
    "# 可写函数说明\n",
    "def printinfo( arg1, *vartuple ):\n",
    "   \"打印任何传入的参数\"\n",
    "   print (\"输出1: \")\n",
    "   print (arg1)\n",
    "   for var in vartuple:\n",
    "      print (\"输出2：\",var)\n",
    "   return\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo( 10 )\n",
    "printinfo( 70, 60, 50 )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#还有一种就是参数带两个星号 **基本语法如下：\n",
    "def functionname([formal_args,] **var_args_dict ):\n",
    "       \"函数_文档字符串\"\n",
    "   function_suite\n",
    "   return [expression]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输出: \n",
      "1\n",
      "{'a': 2, 'b': 3}\n"
     ]
    }
   ],
   "source": [
    "#\n",
    "# 参数带**会以字典的形式导入：\n",
    "#\n",
    "def printinfo( arg1, **vardict ):\n",
    "   #\"打印任何传入的参数\"\n",
    "   print (\"输出: \")\n",
    "   print (arg1)\n",
    "   print (vardict)\n",
    " \n",
    "# 调用printinfo 函数\n",
    "printinfo(1, a=2,b=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#如果单独出现星号 * 后的参数必须用关键字传入\n",
    "def f(a,b,*,c):\n",
    "     return a+b+c\n",
    "#f(1,2,3) \n",
    "f(1,2,c=3) # 正常"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.5匿名函数\n",
    "python 使用 lambda 来创建匿名函数。\n",
    "\n",
    "所谓匿名，意即不再使用 def 语句这样标准的形式定义一个函数。\n",
    "\n",
    "+ lambda 只是一个表达式，函数体比 def 简单很多。\n",
    "+ lambda的主体是一个表达式，而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。\n",
    "+ lambda 函数拥有自己的命名空间，且不能访问自己参数列表之外或全局命名空间里的参数。\n",
    "+ 虽然lambda函数看起来只能写一行，却不等同于C或C++的内联函数，后者的目的是调用小函数时不占用栈内存从而增加运行效率。\n",
    "#### 语法\n",
    "lambda 函数的语法只包含一个语句，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "相加后的值为 :  30\n",
      "相加后的值为 :  40\n"
     ]
    }
   ],
   "source": [
    "'''\n",
    "lambda [arg1 [,arg2,.....argn]]:expression\n",
    "'''\n",
    "sum = lambda arg1, arg2: arg1 + arg2\n",
    " \n",
    "# 调用sum函数\n",
    "print (\"相加后的值为 : \", sum( 10, 20 ))\n",
    "print (\"相加后的值为 : \", sum( 20, 20 ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.6return语句\n",
    "return [表达式] 语句用于退出函数，选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值，以下实例演示了 return 语句的用法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内 :  31\n",
      "函数外 :  30\n"
     ]
    }
   ],
   "source": [
    "#\n",
    "# 带返回值的函数\n",
    "#\n",
    "a=1\n",
    "def sum( arg1, arg2 ):\n",
    "   # 返回2个参数的和.\"\n",
    "   total = arg1 + arg2\n",
    "   print (\"函数内 : \", total+a)\n",
    "   return total\n",
    " \n",
    "# 调用sum函数\n",
    "total = sum( 10, 20 )\n",
    "print (\"函数外 : \", total)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1.7强制位置参数\n",
    "Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数，不能使用关键字参数的形式。\n",
    "\n",
    "在以下的例子中：\n",
    "+ 形参 a 和 b 必须使用指定位置参数\n",
    "+ c 或 d 可以是位置形参或关键字形参\n",
    "+ 而 e 和 f 要求为关键字形参:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "f() takes 4 positional arguments but 5 positional arguments (and 1 keyword-only argument) were given",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_13460/3625861067.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      4\u001b[0m \u001b[1;31m#f(10, 20, 30, d=40, e=50, f=60)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;31m#f(10, b=20, c=30, d=40, e=50, f=60)   # b 不能使用关键字参数的形式\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m20\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m40\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m50\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m60\u001b[0m\u001b[1;33m)\u001b[0m           \u001b[1;31m# e 必须使用关键字参数的形式\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: f() takes 4 positional arguments but 5 positional arguments (and 1 keyword-only argument) were given"
     ]
    }
   ],
   "source": [
    "def f(a, b, /, c, d, *, e, f):\n",
    "    print(a, b, c, d, e, f)\n",
    "\n",
    "#f(10, 20, 30, d=40, e=50, f=60)\n",
    "#f(10, b=20, c=30, d=40, e=50, f=60)   # b 不能使用关键字参数的形式\n",
    "f(10, 20, 30, 40, 50, f=60)           # e 必须使用关键字参数的形式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id = Section2> </a>\n",
    "## 4.2  Python模块\n",
    "用 python 解释器编程，如果你从 Python 解释器退出再进入，那么你定义的所有的方法和变量就都消失了。\n",
    "\n",
    "为此 Python 提供了一个办法，把这些定义存放在文件中，为一些脚本或者交互式的解释器实例使用，这个文件被称为模块。\n",
    "\n",
    "模块是一个包含所有你定义的函数和变量的文件，其后缀名是.py。模块可以被别的程序引入，以使用该模块中的函数等功能。这也是使用 python 标准库的方法。\n",
    "\n",
    "下面是一个使用 python 标准库中模块的例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "命令行参数如下:\n",
      "C:\\Users\\zeng_\\AppData\\Roaming\\Python\\Python310\\site-packages\\ipykernel_launcher.py\n",
      "--ip=127.0.0.1\n",
      "--stdin=9003\n",
      "--control=9001\n",
      "--hb=9000\n",
      "--Session.signature_scheme=\"hmac-sha256\"\n",
      "--Session.key=b\"a1593a76-f9d7-4c26-9836-ab6a2b703892\"\n",
      "--shell=9002\n",
      "--transport=\"tcp\"\n",
      "--iopub=9004\n",
      "--f=c:\\Users\\zeng_\\AppData\\Roaming\\jupyter\\runtime\\kernel-v2-33428Vj4EYwjshKhS.json\n",
      "\n",
      "\n",
      "Python 路径为： ['c:\\\\VSWork\\\\Pythonwork\\\\0001', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\python310.zip', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\DLLs', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\lib', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310', '', 'C:\\\\Users\\\\zeng_\\\\AppData\\\\Roaming\\\\Python\\\\Python310\\\\site-packages', 'C:\\\\Users\\\\zeng_\\\\AppData\\\\Roaming\\\\Python\\\\Python310\\\\site-packages\\\\win32', 'C:\\\\Users\\\\zeng_\\\\AppData\\\\Roaming\\\\Python\\\\Python310\\\\site-packages\\\\win32\\\\lib', 'C:\\\\Users\\\\zeng_\\\\AppData\\\\Roaming\\\\Python\\\\Python310\\\\site-packages\\\\Pythonwin', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\lib\\\\site-packages', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\lib\\\\site-packages\\\\win32', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\lib\\\\site-packages\\\\win32\\\\lib', 'c:\\\\ProgramData\\\\Anaconda3\\\\envs\\\\python310\\\\lib\\\\site-packages\\\\Pythonwin'] \n",
      "\n"
     ]
    }
   ],
   "source": [
    "import sys\n",
    " \n",
    "print('命令行参数如下:')\n",
    "for i in sys.argv:\n",
    "   print(i)\n",
    " \n",
    "print('\\n\\nPython 路径为：', sys.path, '\\n')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "+ 1、import sys 引入 python 标准库中的 sys.py 模块；这是引入某一模块的方法。\n",
    "+ 2、sys.argv 是一个包含命令行参数的列表。\n",
    "+ 3、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2.1 import 语句\n",
    "想使用 Python 源文件，只需在另一个源文件里执行 import 语句，语法如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import module1[, module2[,... moduleN]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个模块只会被导入一次，不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。\n",
    "\n",
    "当我们使用import语句的时候，Python解释器是怎样找到对应的文件的呢？\n",
    "\n",
    "这就涉及到Python的搜索路径，搜索路径是由一系列目录名组成的，Python解释器就依次从这些目录中去寻找所引入的模块。\n",
    "\n",
    "这看起来很像环境变量，事实上，也可以通过定义环境变量的方式来确定搜索路径。\n",
    "\n",
    "搜索路径是在Python编译或安装的时候确定的，安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量，做一个简单的实验，在交互式解释器中，输入以下代码："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "sys.path 输出是一个列表，其中第一项是空串''，代表当前目录（若是从一个脚本中打印出来的话，可以更清楚地看出是哪个目录），亦即我们执行python解释器的目录（对于脚本的话就是运行的脚本所在的目录）。\n",
    "\n",
    "因此若像我一样在当前目录下存在与要引入模块同名的文件，就会把要引入的模块屏蔽掉。\n",
    "\n",
    "了解了搜索路径的概念，就可以在脚本中修改sys.path来引入一些不在搜索路径中的模块。\n",
    "\n",
    "现在，在解释器的当前目录或者 sys.path 中的一个目录里面来创建一个fibo.py的文件，代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 斐波那契(fibonacci)数列模块\n",
    " \n",
    "def fib(n):    # 定义到 n 的斐波那契数列\n",
    "    a, b = 0, 1\n",
    "    while b < n:\n",
    "        print(b, end=' ')\n",
    "        a, b = b, a+b\n",
    "    print()\n",
    " \n",
    "def fib2(n): # 返回到 n 的斐波那契数列\n",
    "    result = []\n",
    "    a, b = 0, 1\n",
    "    while b < n:\n",
    "        result.append(b)\n",
    "        a, b = b, a+b\n",
    "    return result"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后进入Python解释器，使用下面的命令导入这个模块："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "import fibo as f"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 \n"
     ]
    }
   ],
   "source": [
    "f.fib(1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fibo.fib2(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'fibo'"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fibo.__name__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### from … import 语句\n",
    "\n",
    "Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中，语法如下：   \n",
    "from modname import name1[, name2[, ... nameN]]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### from … import * 语句\n",
    "把一个模块的所有内容全都导入到当前的命名空间也是可行的，只需使用如下声明："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from modname import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fibo import fib, fib2\n",
    "fib(500)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id = Section3> </a>\n",
    "## 4.3  Numpy\n",
    "\n",
    "NumPy(Numerical Python) 是 Python 语言的一个扩展程序库，支持大量的维度数组与矩阵运算，此外也针对数组运算提供大量的数学函数库。\n",
    "\n",
    "NumPy 的前身 Numeric 最早是由 Jim Hugunin 与其它协作者共同开发，2005 年，Travis Oliphant 在 Numeric 中结合了另一个同性质的程序库 Numarray 的特色，并加入了其它扩展而开发了 NumPy。NumPy 为开放源代码并且由许多协作者共同维护开发。\n",
    "\n",
    "NumPy 是一个运行速度非常快的数学库，主要用于数组计算，包含：\n",
    "\n",
    "+ 一个强大的N维数组对象 ndarray\n",
    "+ 广播功能函数\n",
    "+ 整合 C/C++/Fortran 代码的工具\n",
    "+ 线性代数、傅里叶变换、随机数生成等功能\n",
    "### NumPy 应用\n",
    "+ NumPy 通常与 SciPy（Scientific Python）和 Matplotlib（绘图库）一起使用， 这种组合广泛用于替代 MatLab，是一个强大的科学计算环境，有助于我们通过 Python 学习数据科学或者机器学习。\n",
    "\n",
    "+ SciPy 是一个开源的 Python 算法库和数学工具包。\n",
    "\n",
    "+ SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。\n",
    "\n",
    "+ Matplotlib 是 Python 编程语言及其数值数学扩展包 NumPy 的可视化操作界面。它为利用通用的图形用户界面工具包，如 Tkinter, wxPython, Qt 或 GTK+ 向应用程序嵌入式绘图提供了应用程序接口（API）。\n",
    "\n",
    "### 相关链接\n",
    "+ NumPy 官网 http://www.numpy.org/\n",
    "+ NumPy 源代码：https://github.com/numpy/numpy\n",
    "+ SciPy 官网：https://www.scipy.org/\n",
    "+ SciPy 源代码：https://github.com/scipy/scipy\n",
    "+ Matplotlib 教程：Matplotlib 教程\n",
    "+ Matplotlib 官网：https://matplotlib.org/\n",
    "+ Matplotlib 源代码：https://github.com/matplotlib/matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 4],\n",
       "       [2, 5],\n",
       "       [3, 6]])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "a=[1,2,3,4,5,6]\n",
    "b=np.array(a)\n",
    "b.resize(2,3)\n",
    "b.transpose()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'NoneType' object has no attribute 'shape'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_1472/3570861396.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0ma\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0.8\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mresize\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m6\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0ma\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      3\u001b[0m \u001b[1;31m#print(a)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'shape'"
     ]
    }
   ],
   "source": [
    "a=np.arange(1,10,0.8).resize(2,6)\n",
    "a.shape\n",
    "#print(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 5)\n"
     ]
    }
   ],
   "source": [
    "b=np.linspace(1,10,10)\n",
    "b=np.array(b)\n",
    "#b=b.reshape(2,5)\n",
    "b.resize(2,5)\n",
    "print(b.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  2.,  3.,  4.,  5.],\n",
       "       [ 6.,  7.,  8.,  9., 10.]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.T\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  2.,  3.,  4.,  5.],\n",
       "       [ 6.,  7.,  8.,  9., 10.]])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b.argmax()\n",
    "b.conjugate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[[ 1.,  2.,  3.,  4.,  5.],\n",
       "         [ 6.,  7.,  8.,  9., 10.]]]])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.squeeze(b)\n",
    "b.resize(1,1,2,5)\n",
    "b.squeeze()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id = Section4> </a>\n",
    "## 4.4  Pandas\n",
    "\n",
    "Pandas 是 Python 语言的一个扩展程序库，用于数据分析。\n",
    "\n",
    "Pandas 是一个开放源码、BSD 许可的库，提供高性能、易于使用的数据结构和数据分析工具。\n",
    "\n",
    "Pandas 名字衍生自术语 \"panel data\"（面板数据）和 \"Python data analysis\"（Python 数据分析）。\n",
    "\n",
    "Pandas 一个强大的分析结构化数据的工具集，基础是 Numpy（提供高性能的矩阵运算）。\n",
    "\n",
    "Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。\n",
    "\n",
    "Pandas 可以对各种数据进行运算操作，比如归并、再成形、选择，还有数据清洗和数据加工特征。\n",
    "\n",
    "Pandas 广泛应用在学术、金融、统计学等各个数据分析领域。用 python 。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Pandas 应用\n",
    "Pandas 的主要数据结构是 Series （一维数据）与 DataFrame（二维数据），这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。\n",
    "\n",
    "### 数据结构\n",
    "+ Series 是一种类似于一维数组的对象，它由一组数据（各种Numpy数据类型）以及一组与之相关的数据标签（即索引）组成。\n",
    "\n",
    "+ DataFrame 是一个表格型的数据结构，它含有一组有序的列，每列可以是不同的值类型（数值、字符串、布尔型值）。DataFrame 既有行索引也有列索引，它可以被看做由 Series 组成的字典（共同用一个索引）。\n",
    "\n",
    "### 相关链接\n",
    "Pandas 官网 https://pandas.pydata.org/\n",
    "Pandas 源代码：https://github.com/pandas-dev/pandas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Unnamed: 0</th>\n",
       "      <th>ts_code</th>\n",
       "      <th>open</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>close</th>\n",
       "      <th>vol</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>trade_date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2021-10-22</th>\n",
       "      <td>0</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>15.25</td>\n",
       "      <td>15.50</td>\n",
       "      <td>15.21</td>\n",
       "      <td>15.25</td>\n",
       "      <td>46717.41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-10-21</th>\n",
       "      <td>1</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>15.26</td>\n",
       "      <td>15.33</td>\n",
       "      <td>15.13</td>\n",
       "      <td>15.20</td>\n",
       "      <td>26697.95</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-10-20</th>\n",
       "      <td>2</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>15.19</td>\n",
       "      <td>15.40</td>\n",
       "      <td>15.13</td>\n",
       "      <td>15.26</td>\n",
       "      <td>31790.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-10-19</th>\n",
       "      <td>3</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>15.38</td>\n",
       "      <td>15.38</td>\n",
       "      <td>15.13</td>\n",
       "      <td>15.22</td>\n",
       "      <td>26657.53</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-10-18</th>\n",
       "      <td>4</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>15.39</td>\n",
       "      <td>15.45</td>\n",
       "      <td>15.23</td>\n",
       "      <td>15.37</td>\n",
       "      <td>28784.58</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999-04-27</th>\n",
       "      <td>4995</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>6.75</td>\n",
       "      <td>6.85</td>\n",
       "      <td>6.56</td>\n",
       "      <td>6.60</td>\n",
       "      <td>6731.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999-04-26</th>\n",
       "      <td>4996</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>7.31</td>\n",
       "      <td>7.48</td>\n",
       "      <td>6.90</td>\n",
       "      <td>6.98</td>\n",
       "      <td>13591.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999-04-23</th>\n",
       "      <td>4997</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>7.65</td>\n",
       "      <td>7.82</td>\n",
       "      <td>7.50</td>\n",
       "      <td>7.67</td>\n",
       "      <td>5243.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999-04-22</th>\n",
       "      <td>4998</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>7.72</td>\n",
       "      <td>7.80</td>\n",
       "      <td>7.30</td>\n",
       "      <td>7.71</td>\n",
       "      <td>11649.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1999-04-21</th>\n",
       "      <td>4999</td>\n",
       "      <td>600848.SH</td>\n",
       "      <td>8.25</td>\n",
       "      <td>8.25</td>\n",
       "      <td>7.80</td>\n",
       "      <td>7.82</td>\n",
       "      <td>13780.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5000 rows × 7 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "            Unnamed: 0    ts_code   open   high    low  close       vol\n",
       "trade_date                                                             \n",
       "2021-10-22           0  600848.SH  15.25  15.50  15.21  15.25  46717.41\n",
       "2021-10-21           1  600848.SH  15.26  15.33  15.13  15.20  26697.95\n",
       "2021-10-20           2  600848.SH  15.19  15.40  15.13  15.26  31790.33\n",
       "2021-10-19           3  600848.SH  15.38  15.38  15.13  15.22  26657.53\n",
       "2021-10-18           4  600848.SH  15.39  15.45  15.23  15.37  28784.58\n",
       "...                ...        ...    ...    ...    ...    ...       ...\n",
       "1999-04-27        4995  600848.SH   6.75   6.85   6.56   6.60   6731.00\n",
       "1999-04-26        4996  600848.SH   7.31   7.48   6.90   6.98  13591.00\n",
       "1999-04-23        4997  600848.SH   7.65   7.82   7.50   7.67   5243.00\n",
       "1999-04-22        4998  600848.SH   7.72   7.80   7.30   7.71  11649.00\n",
       "1999-04-21        4999  600848.SH   8.25   8.25   7.80   7.82  13780.00\n",
       "\n",
       "[5000 rows x 7 columns]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data=pd.read_csv(\"./stocktest/stock600848.csv\",parse_dates=[\"trade_date\"],index_col=[\"trade_date\"])\n",
    "data"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.10.4 ('python310')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "a888cd810c90be07c3c921372a6d7ff433f5a38d5779dfb2a871d99db75673fb"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
